using System;
using DevExpress.Data.Filtering;
using DevExpress.Xpo;
using SmartPeople.Framework.SecuritySpace;

namespace SmartPeople.Framework.Security.Providers.XPO
{
    /// <summary>
    /// 
    /// </summary>
    internal class XPSecuritySecuredDocumentsProvider : ISecuritySecuredDocumentsProvider
    {
        private ISecuritySecuredType defaultPathSecuredType;
        private ISecuritySpace securitySpace;


        public XPSecuritySecuredDocumentsProvider()
        {
            //this.securitySpace = securitySpace;
            //TODO:See if we need to call this update root here ????
            //UpdateRoot();
        }


        public int Count
        {
            get
            {
                XPCollection<XPSecuritySecuredDocument> xpCollection = new XPCollection<XPSecuritySecuredDocument>();
                return xpCollection.Count;
            }
        }


        private ISecuritySecuredType DefaultPathSecuredType
        {
            get
            {
                if (defaultPathSecuredType == null)
                    throw new ArgumentNullException("DefaultPathSecuredType", "Please call SetDefaultPathType first!");
                return defaultPathSecuredType;
            }
        }


        public void SetDefaultPathType(ISecuritySecuredType securedType)
        {
            defaultPathSecuredType = securedType;
            //TODO:Check if this call is a must!!
            //UpdateRoot();
        }


        private void UpdateRoot()
        {
            XPSecuritySecuredDocument rootDocument = GetDocument("/", null);
            if (rootDocument == null)
                //rootDocument = new XPSecuritySecuredDocument("/", defaultPathSecuredType, null);
            {
                rootDocument = new XPSecuritySecuredDocument();
                rootDocument.Name = "/";
                rootDocument.SecuredType = defaultPathSecuredType;
                rootDocument.ParentSecuredDocument = null;
                rootDocument.Save();
            }
            else
            {
                rootDocument.SecuredType = defaultPathSecuredType;
                rootDocument.Save();
            }
        }


        public ISecuritySecuredDocument CreatePath(string pathName, ISecuritySecuredType securedType
                                                   , ISecuritySecuredType defaultChildSecuredType
                                                   , ISecuritySecuredDocument parentSecuredDocument)
        {
            XPSecuritySecuredDocument document = new XPSecuritySecuredDocument();
            document.Name = pathName;
            document.SecuredType = securedType;
            document.ParentSecuredDocument = parentSecuredDocument as XPSecuritySecuredDocument;
            document.DefaultChildSecuredType = defaultChildSecuredType;
            document.Save();
            return document;
        }

        //public ISecuritySecuredDocument CreatePath(string pathName, ISecuritySecuredType securedType
        //                                           , ISecuritySecuredType defaultChildSecuredType
        //                                           , ISecuritySecuredDocument parentSecuredDocument)
        //{
        //    string[] pathParts = pathName.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

        //    XPSecuritySecuredDocument parentDocument = GetDocument("/", null);
        //    int index = 1;

        //    foreach (string pathPart in pathParts)
        //    {
        //        XPSecuritySecuredDocument childDocument = GetDocument(pathPart, parentDocument);
        //        if (childDocument == null)
        //        {
        //            if (index < pathParts.Length)
        //            {
        //                //childDocument = new XPSecuritySecuredDocument(pathPart, DefaultPathSecuredType, parentDocument);
        //                childDocument = new XPSecuritySecuredDocument();
        //                childDocument.Name = pathPart;
        //                childDocument.SecuredType = DefaultPathSecuredType;
        //                childDocument.ParentSecuredDocument = parentDocument;
        //                childDocument.DefaultChildSecuredType = defaultChildSecuredType;
        //                childDocument.Save();
        //            }
        //            else
        //            {
        //                //childDocument = new XPSecuritySecuredDocument(pathPart, securedType, parentDocument);
        //                childDocument = new XPSecuritySecuredDocument();
        //                childDocument.Name = pathPart;
        //                childDocument.SecuredType = securedType;
        //                childDocument.ParentSecuredDocument = parentDocument;
        //                childDocument.DefaultChildSecuredType = defaultChildSecuredType;
        //                childDocument.Save();
        //            }
        //        }
        //        parentDocument = childDocument;
        //        index++;
        //    }
        //    return parentDocument;
        //}


        public ISecuritySecuredDocument CreatePath(string path, ISecuritySecuredType securedType,
                                                   ISecuritySecuredType defaultSecuredType)
        {
            string[] pathParts = path.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);

            XPSecuritySecuredDocument parentDocument = GetDocument("/", null);
            int index = 1;
            foreach (string pathPart in pathParts)
            {
                XPSecuritySecuredDocument childDocument = GetDocument(pathPart, parentDocument);
                if (childDocument == null)
                {
                    if (index < pathParts.Length)
                    {
                        //childDocument = new XPSecuritySecuredDocument(pathPart, DefaultPathSecuredType, parentDocument);
                        childDocument = new XPSecuritySecuredDocument();
                        childDocument.Name = pathPart;
                        childDocument.SecuredType = parentDocument.DefaultChildSecuredType;
                        childDocument.ParentSecuredDocument = parentDocument;
                        childDocument.DefaultChildSecuredType = parentDocument.DefaultChildSecuredType;
                        childDocument.Save();
                    }
                    else
                    {
                        //childDocument = new XPSecuritySecuredDocument(pathPart, securedType, parentDocument);
                        childDocument = new XPSecuritySecuredDocument();
                        childDocument.Name = pathPart;
                        childDocument.SecuredType = securedType;
                        childDocument.ParentSecuredDocument = parentDocument;
                        childDocument.DefaultChildSecuredType = parentDocument.DefaultChildSecuredType;
                        childDocument.Save();
                    }
                }
                parentDocument = childDocument;
                index++;
            }
            return parentDocument;
        }


        public ISecuritySecuredDocument GetDocument(string path)
        {
            string[] pathParts = path.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
            XPSecuritySecuredDocument parentDocument = GetDocument("/", null);
            foreach (string pathPart in pathParts)
            {
                XPSecuritySecuredDocument childDocument = GetDocument(pathPart, parentDocument);
                if (childDocument == null)
                    throw new ArgumentException("Path not found!");
                else
                    parentDocument = childDocument;
            }
            return parentDocument;
        }


        private XPSecuritySecuredDocument GetDocument(string name, ISecuritySecuredDocument parentSecuredDocument)
        {
            GroupOperator criteria = new GroupOperator();
            criteria.Operands.Add(new BinaryOperator("Name", name, BinaryOperatorType.Equal));
            criteria.Operands.Add(
                new BinaryOperator("ParentSecuredDocument", parentSecuredDocument, BinaryOperatorType.Equal));
            XPCollection<XPSecuritySecuredDocument> xpCollection = new XPCollection<XPSecuritySecuredDocument>(criteria);
            if (xpCollection.Count == 1)
            {
                XPSecuritySecuredDocument securedDocument = xpCollection[0];
                return securedDocument;
            }
            return null;
        }


        public ISecuritySecuredDocument GetKnownParentPath(string path)
        {
            string[] pathParts = path.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
            XPSecuritySecuredDocument parentDocument = GetDocument("/", null);
            foreach (string pathPart in pathParts)
            {
                XPSecuritySecuredDocument childDocument = GetDocument(pathPart, parentDocument);
                if (childDocument == null)
                    return parentDocument;
                else
                    parentDocument = childDocument;
            }
            return parentDocument;
        }


        //TODO:Check how to update path and implement
        public void UpdatePath(ISecuritySecuredDocument securityPath)
        {
            //throw new NotImplementedException();
            XPSecuritySecuredDocument secPath = (XPSecuritySecuredDocument) securityPath;
            secPath.Save();
            

        }

        //public ISecuritySecuredDocument CreateDocument(string path, string documentName, string securedTypeName)
        //{
        //    //XPSecuritySecuredDocument childDocument = GetDocument(pathPart, parentDocument);
        //    ////childDocument = new XPSecuritySecuredDocument(pathPart, DefaultPathSecuredType, parentDocument);
        //    //childDocument = new XPSecuritySecuredDocument();
        //    //childDocument.Name = documentName;
        //    //childDocument.SecuredType = DefaultPathSecuredType;
        //    //childDocument.ParentSecuredDocument = parentDocument;
        //    //childDocument.Save();
        //    return null;
        //}

        //public ISecuritySecuredDocument CreateDocument(ISecuritySecuredDocument parentDocument, string documentName
        //    , ISecuritySecuredType securedType)
        //{
        //    XPSecuritySecuredDocument document = new XPSecuritySecuredDocument();
        //    document = new XPSecuritySecuredDocument();
        //    document.Name = documentName;
        //    document.SecuredType = securedType;
        //    document.ParentSecuredDocument = (XPSecuritySecuredDocument) parentDocument;

        //    document.Save();
        //    return document;
        //}


        public void Clear()
        {
            //should not delete root 
            //string rootguid = "{D1C53875-43B4-4d3a-AB9C-BDB5A2354BDE}";
            //CriteriaOperator gidCriteria = new BinaryOperator("GID", rootguid, BinaryOperatorType.NotEqual);

//            string rootguid = "{D1C53875-43B4-4d3a-AB9C-BDB5A2354BDE}";
            GroupOperator criteria = new GroupOperator(GroupOperatorType.And);
  //          criteria.Operands.Add(new BinaryOperator("GID", rootguid, BinaryOperatorType.NotEqual));
            criteria.Operands.Add(new BinaryOperator("Name","/", BinaryOperatorType.NotEqual));
            XPCollection<XPSecuritySecuredDocument> xpCollection =
                new XPCollection<XPSecuritySecuredDocument>(criteria);
            xpCollection.Session.Delete(xpCollection);
        }
    }
}